#=====================================================================
# 3D FFT projections
#
# Base year (year=0) is 2010
#=====================================================================

source ("cmds-inc.R")
source ("cmds-inc--build-legend.R")

Y0 <- 2010
DO_PRINT <- 0

# Configure machine parameters:
#USE_NET_TORUS3D <- FALSE    # Use lower bound from paper
USE_NET_TORUS3D <- TRUE    # Assume a 3D torus

#USE_DOUBLE_PREC <- FALSE  # Assume single-precision values
USE_DOUBLE_PREC <- TRUE

USE_AUTO_SCALING <- FALSE
#USE_AUTO_SCALING <- TRUE

source ("projSys-inc.R")

# Configure FFT parameters:
#USE_LOCAL_EXACT <- FALSE   # Use asymptotic approximation
USE_LOCAL_EXACT <- TRUE    # Use Equ 4 from the paper

source ("algFFT-inc.R")
source ("fftProj3-inc.R")

#=====================================================================
cat (sprintf ("Keeneland analysis\n"))
#=====================================================================

# SC'11 submission uses both 128 and 192 MPI tasks. Here, we consider
# just the 128-task case in determining the number of sockets.

Keeneland_CPU <- newSysPeak (CPU_base, 128*CPU_base@C0 (0))
Keeneland_CPU@desc <- "Keeneland (CPU-only)"
Keeneland_GPU <- newSysPeak (GPU_base, 128*GPU_base@C0 (0))
Keeneland_GPU@desc <- "Keeneland (GPU-only)"

n_Keeneland <- 2048
y_Keeneland <- 0
compareSystems (Keeneland_CPU, Keeneland_GPU, n_Keeneland, y_Keeneland)

qplotSystems (Keeneland_CPU, Keeneland_GPU, n_Keeneland, y_Keeneland)
if (DO_PRINT) ggsave (genRunTagPDF ("keeneland"))

#=====================================================================
cat (sprintf ("Exascale analysis\n"))
#=====================================================================

# First, create a hypothetical GPU system for year 'y', whose peak
# performance 'P' matches the peak predicted in year 'y' by
# 'peakFlops()'.

y <- 10        # Years into the future

# Determine a suitable future problem size, 'n'.
if (USE_AUTO_SCALING) {
  n <- scaleProblem (T__FFT3D, GPU_base, y)
} else {
  n <- 21000     # Problem size
}

P <- peakFlops (y)  # Anticipated peak flops in year y

# Build baseline future GPU system
GPU_sys <- newSysPeak (GPU_base, P)

# ** Scenario 1: Create a CPU system with an identical peak.
CPU_sys__same_peak <- newSysPeak (CPU_base, getPeak (GPU_sys) (y))

compareSystems (CPU_sys__same_peak, GPU_sys, n, y)

# ** Scenario 2: Create a CPU system that computes a 3-D FFT of size
# 'n' in the same total time.

P_cpu <- matchPeak (T__FFT3D, getProc (GPU_sys), P, CPU_base, n, y)
CPU_sys__same_time <- newSysPeak (CPU_base, P_cpu)

compareSystems (CPU_sys__same_time, GPU_sys, n, y)

# ** Scenario 3: Create a CPU system that computes a 3-D FFT of size
# 'n' in the same time, assuming that intra- and inter-node
# communication time can be overlapped.

P_cpu <- matchPeak (T_overlap__FFT3D
                    , getProc (GPU_sys), getPeak (GPU_sys) (y)
                    , CPU_base, n, y)
CPU_sys__same_overlap <- newSysPeak (CPU_base, P_cpu)

compareSystems (CPU_sys__same_overlap, GPU_sys, n, y)

# ** Scenario 4 (Victor Lee @ Intel): Create a GPU system with the
# same bisection bandwidth as the best CPU system.

CPU_baseline <- CPU_sys__same_peak
genFatLink <- function (Baseline, multiplier) {
  return (function (t) {
    if (USE_NET_TORUS3D)
      (multiplier^(2/3)) * getLinkBW (Baseline) (t)
    else
      multiplier * getSocketsLinkBW (Baseline) (t)
  })
}
GPU_beta_fatlink <- genFatLink (CPU_baseline
                                , getSockets (CPU_baseline) (y) / getSockets (GPU_sys) (y))
GPU_fatnet <- newSysPeak (GPU_base, P, beta_link=GPU_beta_fatlink)

compareSystems (CPU_baseline, GPU_fatnet, n, y)

# ** Plot these scenarios **
if (FALSE) {
  qplotSystems (CPU_sys__same_peak, GPU_sys, n, y)
  if (DO_PRINT) ggsave (genRunTagPDF ("exa-fixed-peak"))
  
  qplotSystems (CPU_sys__same_time, GPU_sys, n, y)
  if (DO_PRINT) ggsave (genRunTagPDF ("exa-match-time"))
  
  qplotSystems (CPU_sys__same_overlap, GPU_sys, n, y)
  if (DO_PRINT) ggsave (genRunTagPDF ("exa-match-time-overlap"))
}

##### Merge preceding slots into a single summary plot

Data0b <- rbind (createSysFrame (GPU_sys, n, y, "GPU")
                 , createSysFrame (CPU_sys__same_peak, n, y, "CPU-1: Same Peak")
                 , createSysFrame (CPU_sys__same_time, n, y, "CPU-2: Same Total Time")
                 , createSysFrame (CPU_sys__same_overlap, n, y, "CPU-3: Same Overlap Time"))

if (FALSE)
  Data0b <- rbind (Data0b, createSysFrame (GPU_fatnet, n, y, "GPU-fat: Wider links"))
DummyCol <- data.frame (Arch=rep (" ", length (Data0b$Desc)))
Data0b <- cbind (Data0b, DummyCol)
Data0b$Comm <- factor (Data0b$Comm, c ("Network", "Memory"))

#setDevSlide ()
setDevHD ()

Q0b <- qplot (Arch, Time, data=Data0b
              , fill=Comm, geom="bar", stat="identity", facets=. ~ Desc) +
  geom_text (aes (y=LabelPos, label=round (Time, 3))) +
  scale_x_discrete (name="") +
  scale_y_continuous (name="Time (seconds)") +
  scale_fill_discrete (name="Communication", breaks=rev (levels (Data0b$Comm))) +
  opts (title=sprintf ("3-D FFTs at Exascale: Year=%d, n=%d", Y0+y, n)
        , legend.position="left")
Q0b
if (DO_PRINT) ggsave (genRunTagPDF ("exa-match-summary2"))

#=====================================================================
# Miscellaneous plots
#
# Disabled for now
#=====================================================================

#source ("fftProj3--time-varying.R")
#source ("fftProj3--ipad.R")

# eof
